﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.Compression;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using com.uplus.common.Tools;
using com.uplus.log4net;

namespace com.uplus.common
{
    /// <summary>
    /// Http请求管理类
    /// </summary>
    public class HttpMgr
    {
        static long sPosstion = 0;//本地已下载完的大小
        public delegate void GetDataCompleteHandler(object sender, string responseString);
        public event GetDataCompleteHandler GetDataComplete;

        public delegate void PostDataCompleteHandler(object sender, byte[] responseData, int responseTime,Exception ex=null);
        public event PostDataCompleteHandler PostDataComplete;

        /// <summary>
        /// GetResponseStateComplete
        /// </summary>
        /// <param name="sender">HttpWebRequest</param>
        /// <param name="statusCode">请求状态码</param>
        /// <param name="responseTime">响应时间</param>
        public delegate void GetResponseStateCompleteHandler(object sender, string statusCode, int responseTime);
        public event GetResponseStateCompleteHandler GetResponseStateComplete;

        public static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {  // 总是接受  
            return true;
        }

        #region 向指定地址发送请求，并返回页面源代码
        /// <summary>
        /// 向指定地址发送请求，并返回页面源代码
        /// </summary>
        /// <param name="url"></param>
        /// <param name="code">文档编码</param>
        /// <returns></returns>
        public static string GetData(string url, string code)
        {
            string re = null;
            try
            {
                ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
                WebClient wc = new WebClient();
                wc.Credentials = CredentialCache.DefaultCredentials;
                byte[] data = wc.DownloadData(url);
                re = Encoding.GetEncoding(code).GetString(data);
            }
            catch
            { }
            return re;
        }

        public static byte[] GetData(string url)
        {
            byte[] data = null;
            try
            {
                WebClient wc = new WebClient();
                wc.Credentials = CredentialCache.DefaultCredentials;
                data = wc.DownloadData(url);
            }
            catch
            { }
            return data;
        }



        #endregion

        #region 向指定地址上传文件，并返回页面源代码
        /// <summary>
        /// 向指定地址上传文件，并返回页面源代码
        /// </summary>
        /// <param name="url"></param>
        /// <param name="code">文档编码</param>
        /// <param name="file">要上传的文件</param>
        /// <returns></returns>
        public static string UploadFile(string url, string code, string file)
        {
            string re = null;
            // 创建一个新的 WebClient 实例.
            WebClient myWebClient = new WebClient();
            // 直接上传，并获取返回的二进制数据.
            byte[] data = myWebClient.UploadFile(url, "POST", file);
            re = Encoding.GetEncoding(code).GetString(data);
            return re;
        }
        #endregion

        #region ResetLength
        public static string ResetLength(string url, string code)
        {
            string re = "";
            WebClient client = new WebClient();
            client.Credentials = CredentialCache.DefaultCredentials;
            byte[] data = client.DownloadData(url);
            re = Encoding.GetEncoding(code).GetString(data);
            return re;
        }
        #endregion

        #region 向指定地址发送数据，并返回页面源代码
        /// <summary>
        /// 向指定地址发送数据，并返回页面源代码
        /// </summary>
        /// <param name="url"></param>
        /// <param name="code">文档编码</param>
        /// <param name="nameValues">要上传的文件</param>
        /// <returns></returns>
        public static string PostData(string url, string code, Dictionary<string, string> nameValues)
        {
            string re = null;
            WebClient myWebClient = new WebClient();

            System.Collections.Specialized.NameValueCollection nv = new System.Collections.Specialized.NameValueCollection();
            foreach (KeyValuePair<string, string> item in nameValues)
            {
                nv.Add(item.Key, item.Value);
            }

            byte[] data = myWebClient.UploadValues(url, "POST", nv);
            re = Encoding.GetEncoding(code).GetString(data);
            return re;
        }
        #endregion

        #region 在网络上下载文件

        #region DownFile
        /// <summary>
        /// 在指定的URL下载文件
        /// </summary>
        /// <param name="url">url地址</param>
        /// <param name="fileName">保存在本地的文件名（包括路径）</param>
        public static bool DownFile(string url, string fileName)
        {
            HttpWebRequest hwr = (HttpWebRequest)HttpWebRequest.Create(url);
            HttpWebResponse myrp = (System.Net.HttpWebResponse)hwr.GetResponse(); //从WEB请求得到WEB响应   
            long totalBytes = myrp.ContentLength; //从WEB响应得到总字节数
            myrp.Close();

            Log(string.Format("准备下载{0}文件，文件总大小为{1}KB", fileName.Substring(fileName.LastIndexOf(@"\") + 1), (totalBytes / 1024)));

            FileInfo fInfo = new FileInfo(fileName);

            if (File.Exists(fileName) && totalBytes == fInfo.Length)
            {
                Log("文件已被完整的下载，本次无需下载......");
                return true;
            }

            Log("开始下载，下载失败后会断点下载......");

            int i = 5;
            var tmp = i;
            while (true)
            {
                i--;
                try
                {
                    WebClient downFile = new WebClient();
                    downFile.DownloadFile(url, fileName);
                }
                catch
                {
                    Log(string.Format("第{0}次下载失败，一共尝试10次下载", 5 - i));
                }

                fInfo = new FileInfo(fileName);
                if (File.Exists(fileName) && totalBytes == fInfo.Length)
                {
                    Log("文件下载成功......");
                    return true;
                }
                else
                {
                    if (i == 0)
                    {
                        Log(string.Format("{0}次尝试下载失败，放弃下载该文件，继续下一个文件下载......", tmp));
                        throw new Exception(string.Format("文件{0}下载到{1}失败", url, fileName));
                        return false;
                    }
                    System.Threading.Thread.Sleep(1000);

                }
            }
        }
        #endregion

        #region DownloadFile（以断点续传方式下载文件）
        /// <summary>
        /// 以断点续传方式下载文件
        /// </summary>
        /// <param name="strUrl">文件下载地址</param>
        /// <param name="strFileName">下载文件的保存路径</param>
        public static void DownloadFile(string strUrl, string strFileName)
        {
            int i = 5;
            while (true)
            {
                i--;
                //打开上次下载的文件或新建文件
                int CompletedLength = 0;//记录已完成的大小

                FileStream FStream;
                if (File.Exists(strFileName))
                {
                    FStream = File.OpenWrite(strFileName);
                    sPosstion = FStream.Length;
                    FStream.Seek(sPosstion, SeekOrigin.Current);//移动文件流中的当前指针
                }
                else
                {
                    FStream = new FileStream(strFileName, FileMode.Create);
                    sPosstion = 0;
                }
                try
                {
                    //打开网络连接
                    HttpWebRequest myRequest = (HttpWebRequest)HttpWebRequest.Create(strUrl);
                    myRequest.Timeout = 100 * 1000;
                    myRequest.ReadWriteTimeout = 30 * 1000;
                    //设置Range值
                    myRequest.AddRange((int)sPosstion);
                    //向服务器请求，获得服务器的回应数据流
                    HttpWebResponse webResponse = (HttpWebResponse)myRequest.GetResponse();

                    long FileLength = webResponse.ContentLength;//文件大小
                    Stream myStream = webResponse.GetResponseStream();
                    byte[] btContent = new byte[1024];

                    while ((CompletedLength = myStream.Read(btContent, 0, 1024)) > 0)
                    {
                        FStream.Write(btContent, 0, CompletedLength);
                    }

                    FStream.Close();
                    myStream.Close();
                    break;
                }
                catch (Exception ex)
                {
                    FStream.Close();
                    if (ex.Message.Contains("416")) return;
                }
                if (i == 0)
                {
                    throw new Exception(string.Format("从{0}下载文件到{1}失败", strUrl, strFileName));
                    return;
                }
                System.Threading.Thread.Sleep(200);
            }
        }
        #endregion

        #endregion

        #region PostData
        public static string PostData(string strUrl, string postData)
        {
            return PostData(strUrl, postData, Encoding.UTF8);
        }

        public static string PostData(string strUrl,string postData, Encoding encode, string contentType = "application/json")
        {
            HttpWebRequest hwrq = null;
            HttpWebResponse hwrp = null;
            StreamReader sr = null;
            string strMain = null;
            try
            {
                hwrq = (HttpWebRequest)WebRequest.Create(strUrl);
                hwrq.Method = "post";

                byte[] dataByte = encode.GetBytes(postData);
                hwrq.ContentLength = dataByte.Length;
                Stream sm1 = hwrq.GetRequestStream();
                sm1.Write(dataByte, 0, dataByte.Length);
                sm1.Close();

                hwrq.ContentType = contentType;
                hwrp = (HttpWebResponse)hwrq.GetResponse();
                sr = new StreamReader(hwrp.GetResponseStream(), encode);
                strMain = sr.ReadToEnd();
            }
            catch
            {
                strMain = null;
            }
            finally
            {
                if (sr != null)
                {
                    sr.Close();
                    sr = null;
                }
                if (hwrp != null)
                {
                    hwrp.Close();
                    hwrp = null;
                }
            }
            return strMain;
        }
        #endregion

        #region PutData
        /// <summary>
        /// 
        /// </summary>
        /// <param name="data"></param>
        /// <param name="url"></param>
        /// <param name="method"></param>
        /// <param name="contentType"></param>
        /// <param name="encodingCode"></param>
        /// <returns></returns>
        public void PutData(Dictionary<string, string> headers, byte[] data, string url, string contentType, string encodingCode, string accept)
        {
            CommonHttpRequest(headers, data, url, "PUT", contentType, encodingCode, accept);
        }
        #endregion

        #region PostData
        /// 创建POST方式的HTTP请求  
        public static HttpWebResponse PostHttpResponse(string url, IDictionary<string, object> parameters = null, string postdata = null)
        {
            HttpWebRequest request = null;
            //如果是发送HTTPS请求  
            if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
            {
                request = WebRequest.Create(url) as HttpWebRequest;

            }
            else
            {
                request = WebRequest.Create(url) as HttpWebRequest;
            }
            request.Method = "POST";
            request.ContentType = "application/json";
            //发送POST数据  
            if (!(parameters == null || parameters.Count == 0))
            {
                StringBuilder buffer = new StringBuilder();
                int i = 0;
                foreach (string key in parameters.Keys)
                {
                    if (i > 0)
                    {
                        buffer.AppendFormat("&{0}={1}", key, parameters[key]);
                    }
                    else
                    {
                        buffer.AppendFormat("{0}={1}", key, parameters[key]);
                        i++;
                    }
                }
                byte[] data = Encoding.ASCII.GetBytes(buffer.ToString());
                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
            }
            if (postdata?.Length > 0 && postdata != null)
            {
                byte[] data = Encoding.ASCII.GetBytes(postdata);
                using (Stream stream = request.GetRequestStream())
                {
                    stream.Write(data, 0, data.Length);
                }
            }
            string[] values = request.Headers.GetValues("Content-Type");
            return request.GetResponse() as HttpWebResponse;
        }


        /// <summary>
        /// 获取请求的数据
        /// </summary>
        public static string GetResponseString(HttpWebResponse webresponse)
        {
            using (Stream s = webresponse.GetResponseStream())
            {
                StreamReader reader = new StreamReader(s, Encoding.UTF8);
                return reader.ReadToEnd();

            }
        }
        #region Post数据，无返回，可以通过事件获取返回数据
        /// <summary>
        /// Post数据，无返回，可以通过事件获取返回数据
        /// </summary>
        /// <param name="headers"></param>
        /// <param name="data"></param>
        /// <param name="url"></param>
        /// <param name="contentType"></param>
        /// <param name="encodingCode"></param>
        /// <param name="accept"></param>
        public void PostData(Dictionary<string, string> headers, byte[] data, string url, string contentType, string encodingCode, string accept)
        {
            CommonHttpRequest(headers, data, url, "POST", contentType, encodingCode, accept);
        }
        #endregion

        #region  Post数据，并返回byte数组
        /// <summary>
        /// Post数据，并返回byte数组
        /// </summary>
        /// <param name="headers"></param>
        /// <param name="data"></param>
        /// <param name="url"></param>
        /// <param name="contentType"></param>
        /// <param name="encodingCode"></param>
        /// <param name="accept"></param>
        /// <returns></returns>

        public byte[] PostDataByte(Dictionary<string, string> headers, byte[] data, string url, string contentType, string encodingCode, string accept)
        {
            return CommonHttpRequest(headers, data, url, "POST", contentType, encodingCode, accept);
        }
        #endregion

        #endregion

        #region GetData
        public void GetData(Dictionary<string, string> headers, byte[] data, string url, string contentType, string encodingCode, string accept)
        {

            CommonHttpRequest(headers, data, url, "GET", contentType, encodingCode, accept);
        }

        /// <summary>
        /// zt HttpGet
        /// </summary>
        /// <param name="headers"></param>
        /// <param name="data"></param>
        /// <param name="url"></param>
        /// <param name="contentType"></param>
        /// <param name="encodingCode"></param>
        /// <param name="accept"></param>
        /// <returns></returns>
        public byte[] GetResultData(Dictionary<string, string> headers, byte[] data, string url, string contentType, string encodingCode, string accept)
        {

           return  CommonHttpRequest(headers, data, url, "GET", contentType, encodingCode, accept);
        }

        public string GetResponseState(Dictionary<string, string> headers, byte[] data, string url, string contentType, string encodingCode, string accept)
        {
            string re = "";
            //Web访问对象，构造请求的url地址
            string serviceUrl = url;

            //构造http请求的对象
            DateTime startTime = DateTime.Now;
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceUrl);
            System.Net.ServicePointManager.DefaultConnectionLimit = 1024;
            //转成网络流
            //设置
            foreach (string item in headers.Keys)
            {
                request.Headers.Add(item, headers[item]);
            }
            request.ProtocolVersion = HttpVersion.Version10;
            request.Method = "GET";
            request.ContentLength = data.Length;
            request.ContentType = contentType;//"application/json";
            request.MaximumAutomaticRedirections = 10;
            request.AllowAutoRedirect = true;
            request.Accept = accept;//"application/json";
            request.KeepAlive = true;
            request.Timeout = 20 * 1000;

            if (request.ContentLength > 0)
            {
                // 发送请求
                Stream newStream = request.GetRequestStream();
                newStream.Write(data, 0, data.Length);
                newStream.Close();
            }

            // 获得接口返回值

            HttpWebResponse response = null;
            try
            {
                response = (HttpWebResponse)request.GetResponse();
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    re = "200";
                }
                else
                {
                    re = ((int)response.StatusCode).ToString();
                }
                if (GetResponseStateComplete != null)
                {
                    DateTime endTime = DateTime.Now;
                    int resTime = Convert.ToInt32((endTime - startTime).TotalMilliseconds);//获取响应时间
                    GetResponseStateComplete(request, re, resTime);
                }
                response.Close();
            }
            catch (WebException ex)
            {
                re = "1003";
                Log4Helper.Error(url, "GetResponseState异常", ex);
                if (GetResponseStateComplete != null)
                {
                    DateTime endTime = DateTime.Now;
                    int resTime = Convert.ToInt32((endTime - startTime).TotalMilliseconds);//获取响应时间
                    GetResponseStateComplete(request, re, resTime);
                }
            }
            finally
            {
                if (response != null)
                    response.Close();
                response = null;
                if (request != null)
                    request.Abort();
                request = null;

            }
            return re;
        }



        public Task<string> GetResponseStateAsync(Dictionary<string, string> headers, byte[] data, string url, string contentType, string encodingCode, string accept)
        {
            LimitedConcurrencyLevelTaskScheduler lcts = new LimitedConcurrencyLevelTaskScheduler(1024);
            TaskFactory factory = new TaskFactory(lcts);
            return Task.Run<string>(() =>
            {
                string re = "";
                //Web访问对象，构造请求的url地址
                string serviceUrl = url;

                //构造http请求的对象
                DateTime startTime = DateTime.Now;
                System.GC.Collect();
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(serviceUrl);
                System.Net.ServicePointManager.DefaultConnectionLimit = int.MaxValue;
                //转成网络流
                //设置
                foreach (string item in headers.Keys)
                {
                    request.Headers.Add(item, headers[item]);
                }
                request.Method = "GET";
                request.ContentLength = data.Length;
                request.ContentType = contentType;//"application/json";
                request.MaximumAutomaticRedirections = 10;
                request.AllowAutoRedirect = true;
                request.Accept = accept;//"application/json";
                request.KeepAlive = false;
                request.Timeout = 20 * 1000;

                if (request.ContentLength > 0)
                {
                    // 发送请求
                    Stream newStream = request.GetRequestStream();
                    newStream.Write(data, 0, data.Length);
                    newStream.Close();
                }

                // 获得接口返回值

                HttpWebResponse response = null;
                try
                {
                    response = (HttpWebResponse)request.GetResponse();
                    if (response.StatusCode == HttpStatusCode.OK)
                    {
                        re = "200";
                    }
                    else
                    {
                        re = ((int)response.StatusCode).ToString();
                    }
                    if (GetResponseStateComplete != null)
                    {
                        DateTime endTime = DateTime.Now;
                        int resTime = Convert.ToInt32((endTime - startTime).TotalMilliseconds);//获取响应时间
                        GetResponseStateComplete(request, re, resTime);
                    }
                    response.Close();
                }
                catch (WebException ex)
                {
                    re = "1003";
                    Log4Helper.Error(url, "GetResponseState异常", ex);
                    if (GetResponseStateComplete != null)
                    {
                        DateTime endTime = DateTime.Now;
                        int resTime = Convert.ToInt32((endTime - startTime).TotalMilliseconds);//获取响应时间
                        GetResponseStateComplete(request, re, resTime);
                    }
                }
                finally
                {
                    if (response != null)
                        response.Close();
                    response = null;
                    if (request != null)
                        request.Abort();
                    request = null;

                }
                return re;
            });
        }
        #endregion

        #region DeleteData
        public void DeleteData(Dictionary<string, string> headers, byte[] data, string url, string contentType, string encodingCode, string accept)
        {

            CommonHttpRequest(headers, data, url, "DELETE", contentType, encodingCode, accept);
        }
        #endregion

        #region CommonHttpRequest
        private byte[] CommonHttpRequest(Dictionary<string, string> headers, byte[] data, string url, string method, string contentType, string encodingCode, string accept)
        {

            //Web访问对象，构造请求的url地址
            System.GC.Collect();
            System.Net.ServicePointManager.DefaultConnectionLimit = 256;
            //构造http请求的对象
            DateTime startTime = DateTime.Now;
            ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback(CheckValidationResult);
            HttpWebRequest request = (HttpWebRequest)WebRequest.CreateHttp(url);
            //转成网络流
            //byte[] buf = System.Text.Encoding.GetEncoding(encodingCode).GetBytes(data);//"UTF-8"
            //设置
            if(null != headers)
            {
                foreach (string item in headers.Keys)
                {
                    request.Headers.Add(item, headers[item]);
                }
            }
            request.ProtocolVersion = HttpVersion.Version11;
            request.Method = method;
            request.ContentLength = data.Length;
            request.ContentType = contentType;//"application/json";
            request.MaximumAutomaticRedirections = 1;
            request.AllowAutoRedirect = true;
            request.Accept = accept;//"application/json";
            request.KeepAlive = false;
            request.AutomaticDecompression = DecompressionMethods.GZip;
            request.Proxy = null;
            request.Timeout = 60*1000;



            if (request.ContentLength > 0)
            {
                // 发送请求
                Stream newStream = request.GetRequestStream();
                newStream.Write(data, 0, data.Length);
                newStream.Close();
            }

            // 获得接口返回值
            //string re = "";
            byte[] resData = null;
            try
            {
                using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
                {
                    resData = ReadStream(response.GetResponseStream());//Encoding.UTF8.GetBytes(read.ReadToEnd());
                    if (PostDataComplete != null)
                    {
                        DateTime endTime = DateTime.Now;
                        int resTime = Convert.ToInt32((endTime - startTime).TotalMilliseconds);//获取相应时间
                        PostDataComplete(request, resData, resTime);
                    }
                    response.Dispose();
                }
            }
            catch (WebException ex)
            {
                if (PostDataComplete != null)
                {
                    DateTime endTime = DateTime.Now;
                    int resTime = Convert.ToInt32((endTime - startTime).TotalMilliseconds);//获取相应时间
                    PostDataComplete(request, resData, resTime, ex);
                }
                Log4Helper.Error(url, "CommonHttpRequest异常", ex);
            }
            finally
            {
                if (request != null) request.Abort();
                request = null;
            }


            return resData;
        }
        #endregion

        public static byte[] ReadStream(Stream input)
        {
            byte[] buffer = new byte[16 * 1024];
            using (MemoryStream ms = new MemoryStream())
            {
                int read;
                while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                return ms.ToArray();
            }
        }

        #region 写日志
        static string strLock = "";
        protected static void Log(string txt)
        {
            lock (strLock)
            {
                File.AppendAllText(
                    string.Format(@"{0}\FlowLog.log", AppDomain.CurrentDomain.BaseDirectory),
                    string.Format("{0:yyyy-MM-dd HH:mm:ss}\t{1}\r\n", DateTime.Now, txt));
            }
        }
        #endregion


        #region Alios Request Method
        /// <summary>
        /// 执行HTTP POST请求。
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="textParams">请求文本参数</param>
        /// <param name="headerParams">请求头部参数</param>
        /// <returns>HTTP响应</returns>
        public string DoPost(string url, IDictionary<string, string> textParams, IDictionary<string, string> headerParams)
        {
            //LimitedConcurrencyLevelTaskScheduler lclt = new LimitedConcurrencyLevelTaskScheduler(1024); 限制异步线程池数量
            //TaskFactory factory = new TaskFactory(lclt);
            HttpWebRequest req = null;
            HttpWebResponse rsp = null;
            Encoding encoding = null;
            DateTime starttime = DateTime.Now;
            try
            {
                System.GC.Collect();
                System.Net.ServicePointManager.DefaultConnectionLimit = 1024;
                req = (HttpWebRequest)WebRequest.Create(url);
                req.Method = "POST";
                req.KeepAlive = false;
                req.Timeout = 20 * 1000;
                req.ContentType = "application/x-www-form-urlencoded;charset=utf-8";
                req.AutomaticDecompression = DecompressionMethods.GZip;//如果压缩 自动解压缩
                byte[] postData = Encoding.UTF8.GetBytes(BuildQuery(textParams));
                System.IO.Stream reqStream = req.GetRequestStream();
                reqStream.Write(postData, 0, postData.Length);
                reqStream.Close();
                rsp = (HttpWebResponse)req.GetResponse();
                DateTime endtime = DateTime.Now;
                encoding = GetResponseEncoding(rsp);
                return GetResponseAsString(rsp, encoding, starttime, req);
            }
            catch (Exception ex)
            {
                Log4Helper.Error("IAdRequest/AliosAdRequest/AdRequestHandler", "DoPost异常", ex);
                return null;
            }
            finally
            {
                if (rsp != null) rsp.Close();
                if (req != null) req.Abort();
                rsp = null;
                req = null;
            }


        }

        /// <summary>
        /// 组装普通文本请求参数。
        /// </summary>
        /// <param name="parameters">Key-Value形式请求参数字典</param>
        /// <returns>URL编码后的请求数据</returns>
        public static string BuildQuery(IDictionary<string, string> parameters)
        {
            if (parameters == null || parameters.Count == 0)
            {
                return null;
            }

            StringBuilder query = new StringBuilder();
            bool hasParam = false;

            foreach (KeyValuePair<string, string> kv in parameters)
            {
                string name = kv.Key;
                string value = kv.Value;
                // 忽略参数名或参数值为空的参数
                if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
                {
                    if (hasParam)
                    {
                        query.Append("&");
                    }

                    query.Append(name);
                    query.Append("=");
                    query.Append(HttpUtility.UrlEncode(value, Encoding.UTF8));
                    hasParam = true;
                }
            }

            return query.ToString();
        }

        private Encoding GetResponseEncoding(HttpWebResponse rsp)
        {
            string charset = rsp.CharacterSet;
            if (string.IsNullOrEmpty(charset))
            {
                charset = "utf-8";
            }
            return Encoding.GetEncoding(charset);
        }

        /// <summary>
        /// 把响应流转换为文本。
        /// </summary>
        /// <param name="rsp">响应流对象</param>
        /// <param name="encoding">编码方式</param>
        /// <returns>响应文本</returns>
        public string GetResponseAsString(HttpWebResponse rsp, Encoding encoding, DateTime startTime, HttpWebRequest req)
        {
            Stream stream = null;
            StreamReader reader = null;
            string result = string.Empty;

            try
            {
                // 以字符流的方式读取HTTP响应
                stream = rsp.GetResponseStream();
                if ("gzip".Equals(rsp.ContentEncoding, StringComparison.OrdinalIgnoreCase))
                {
                    stream = new GZipStream(stream, CompressionMode.Decompress);
                }
                reader = new StreamReader(stream, encoding);
                if (PostDataComplete != null)
                {
                    DateTime endTime = DateTime.Now;
                    int resTime = Convert.ToInt32((endTime - startTime).TotalMilliseconds);//获取相应时间
                    result = reader.ReadToEnd();
                    PostDataComplete(req, Encoding.UTF8.GetBytes(result), resTime);
                }
                return result;
            }
            finally
            {
                // 释放资源
                if (reader != null) reader.Close();
                if (stream != null) stream.Close();
            }
        }
        #endregion

    }
}
